home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / pascala.zip / AIRPORT2.PAS < prev    next >
Pascal/Delphi Source File  |  1991-05-06  |  16KB  |  448 lines

  1. PROGRAM Airort(Input, Output);
  2. (********************************************************)
  3. (*  Pre-Cond: The user must supply the number of time   *)
  4. (*            intervals, the arrival and departure      *)
  5. (*            rates per time interval.                  *)
  6. (*  Post-Cond: The program performs a random simulation *)
  7. (*             of the airport, showing the summary of   *)
  8. (*             various statistics and the log of run    *)
  9. (*             use.                                     *)
  10. (*  From Kruse, out of PRB 1/31/91                      *)
  11. (********************************************************)
  12.  
  13. (*****************************************)
  14. (*  Alejo Alamillo    COSC 055         *)
  15. (*  Spring 1991          Assignment Airport *)
  16. (*****************************************)
  17.  
  18.  
  19.  
  20.   CONST  QueueSize = 5;
  21.   TYPE  PlaneRecType = RECORD
  22.                          ID,
  23.                          TimeOnQ: Integer;
  24.                        END;
  25.         QueueEntry = PlaneRecType;   (* Alias for QueuePack *)
  26.  
  27.         QueueType = RECORD           (* Array implementation *)
  28.                       Count,
  29.                       Front,
  30.                       Rear: Integer;
  31.                       Entry: ARRAY[0..QueueSize] OF QueueEntry;
  32.                     END;
  33. VAR  LandingQ,
  34.      TakeoffQ:       Queuetype;
  35.      CurrentPlane:   PlaneRecType;
  36.      BackLog:        Boolean;
  37.      Counter,
  38.      CurrentTime,
  39.      EndTime,
  40.      Seed,
  41.      NumberOfPlanes,
  42.      NumberOfLandings,
  43.      NumberOfTakeoffs,
  44.      NumberRefused,
  45.      TotalLandingWait,
  46.      TotalTakeoffWait,
  47.      MaximumLandingWait,
  48.      MaximumTakeoffWait,
  49.      Idletime,
  50.      IdletimeLand,
  51.      IdletimeTakeoff:           Integer;
  52.  
  53. (*****************************************************************)
  54.  
  55.      ExpectedArrivals,
  56.      ExpectedDepartures: Real;
  57.  
  58. (*********************************************************)
  59. (*  QUEUEPACK routines follow:                           *)
  60. (*********************************************************)
  61.  
  62. (***********************************************)
  63. (*  Pre-Cond:  None                            *)
  64. (*  Post-Cond: An empty Q has been created     *)
  65. (***********************************************)
  66. PROCEDURE CreateQ( VAR Q: QueueType);
  67.   BEGIN
  68.   WITH Q DO
  69.     BEGIN
  70.     Count:= 0;
  71.     Front:= 1;
  72.     Rear:=  0;
  73.     END;
  74.   END;
  75. (***********************************************)
  76. (* Pre-Cond: The Queue has been created.       *)
  77. (* Post-Cond: Obvious.                         *)
  78. (***********************************************)
  79. FUNCTION FullQ(VAR Q: QueueType): Boolean;
  80.   BEGIN
  81.   IF ((Q.Rear + 2) MOD QueueSize = (Q.Front MOD QueueSize) ) THEN
  82.     FullQ:= True
  83.   ELSE
  84.     FullQ:= False;
  85.   END;
  86.  
  87. FUNCTION EmptyQ( VAR Q: QueueType): Boolean;
  88.   BEGIN
  89.   IF ((Q.Rear + 1) MOD QueueSize = (Q.Front MOD QueueSize)) THEN
  90.     EmptyQ:= True
  91.   ELSE
  92.     EmptyQ:= False;
  93.   END;
  94.  
  95. (***********************************************)
  96. (*  Pre-Cond: Q has been created               *)
  97. (*  Post-Cond: Item has been added at the      *)
  98. (*             rear of the Q                   *)
  99. (***********************************************)
  100. PROCEDURE Append(VAR Q: QueueType; NewItem: QueueEntry);
  101.   BEGIN
  102.   WITH Q DO
  103.     BEGIN
  104.     IF (not FullQ(Q)) THEN
  105.       BEGIN
  106.       Rear:= (Rear MOD QueueSize) + 1;
  107.       Entry[Rear]:= NewItem;
  108.       END
  109.     ELSE
  110.       Writeln('ERROR--Q overflow');
  111.     END;
  112.   END;
  113. (**************************************************)
  114. (*  Pre-Cond: Q has been created                  *)
  115. (*  Post-Cond: The first item on the Q hs been    *)
  116. (*             removed and copied to ItemFromQ    *)
  117. (**************************************************)
  118. PROCEDURE Serve(VAR Q: QueueType; VAR ItemFromQ: QueueEntry);
  119.   BEGIN
  120.   WITH Q DO
  121.     BEGIN
  122.     IF (not EmptyQ(Q)) THEN
  123.       BEGIN
  124.       Count:= Count - 1;
  125.       ItemFromQ:= Entry[Front];
  126.       Front:= (Front MOD QueueSize) + 1;
  127.       END
  128.     ELSE
  129.       Writeln('ERROR--Attempt to serve an empty Q');
  130.     END;
  131.   END;
  132. (*******************************************************)
  133. (*    Random function                                  *)
  134. (*  Pre-Cond: a seed has been initialized              *)
  135. (*  Post-Cond: Random is a uniformly distributed R V   *)
  136. (*             and a new Seed has been generated.      *)
  137. (*******************************************************)
  138. FUNCTION Random(VAR Seed: Integer): Real;
  139.   CONST  Modulus = 65536;
  140.          Multiplier = 25173;
  141.          Increment = 13849;
  142.   BEGIN
  143.   Seed:= ((Multiplier*Seed) + Increment) MOD Modulus;
  144.   Random:= Seed/Modulus;
  145.   END;
  146. (************************************************************)
  147. (* Pre-Cond: An expected value and a Seed have been pre-set *)
  148. (* Post-Cond: An integer in the range: 0... is generated    *)
  149. (*            with a poisson distribution                   *)
  150. (************************************************************)
  151. FUNCTION Poisson(ExpectedValue: Real): Integer;
  152.   VAR Limit,
  153.       Product: Real;
  154.       Count: Integer;
  155.   BEGIN
  156.   Count:= 0;
  157.   Limit:= Exp(-ExpectedValue);    (* Exponential function *)
  158.   Product:= Random(Seed);
  159.  
  160.   WHILE (Product > Limit) DO
  161.     BEGIN
  162.     Count:= Count + 1;
  163.     Product:= Product*Random(Seed);
  164.     END;  (*** WHILE ***)
  165.  
  166.   Poisson:= Count;
  167.   END;
  168. (********************   End of QueuePack  ******************)
  169. (***********************************************************)
  170. (* Pre-Cond: None.                                         *)
  171. (* Post- Cond: All variables are initialized               *)
  172. (***********************************************************)
  173. PROCEDURE Initialize;
  174.   VAR GoodInput: Boolean;
  175.   BEGIN
  176.   BackLog := False;
  177.   NumberOfPlanes:= 0;
  178.   NumberofLandings:= 0;
  179.   NumberOfTakeoffs:= 0;
  180.   NumberRefused:= 0;
  181.   TotalLandingWait:= 0;
  182.   TotalTakeoffWait:= 0;
  183.   Idletime:= 0;
  184.   CurrentTime:=0;
  185.   Writeln('This program simulates the activity at an airport with');
  186.   Writeln('two runways.  Two planes can land or takeoff ');
  187.   Writeln('in each time interval of the simulation');
  188.   Writeln; Write('How many time periods in the simulation? ');
  189.   Readln(EndTime);
  190.   Writeln;
  191.   Write('Enter a seed integer for the random function: ');
  192.   Readln(Seed);
  193.   Writeln;
  194.  
  195.   REPEAT
  196.     Write('Enter the expected number of arrivals and departures--');
  197.     Readln(ExpectedArrivals, ExpectedDepartures);     Writeln;
  198.     IF ((ExpectedArrivals + ExpectedDepartures) >= 2.0) THEN
  199.       Writeln('These must be positive real numbers with total less than 1 ')
  200.     ELSE                            (* Lest the Queues overflow regularly *)
  201.       GoodInput:= True;
  202.   UNTIL GoodInput;
  203. END; (****************  Initialize  *****************************)
  204. (*******************************************************************)
  205. (*  Pre-Cond: None.                                                *)
  206. (*  Post-Cond: Processes a plane attempting to access a full queue *)
  207. (*******************************************************************)
  208. PROCEDURE Refuse(CurrentPlane: PlaneRecType; VAR NumberRefused: Integer);
  209.   BEGIN
  210.   Writeln('Queue is full, plane delayed');
  211.   NumberRefused:= NumberRefused + 1;
  212.   END;
  213. (******************************************************************)
  214. (* Pre-Cond: None.                                                *)
  215. (* Post-Cond: Revises data for landing CurrentPlane               *)
  216. (******************************************************************)
  217. PROCEDURE Land(CurrentPlane: PlaneRecType;
  218.                  CurrentTime: Integer;
  219.                  VAR NumberLanded,
  220.                      TotalLandingWait,
  221.                      MaximumLandingWait: Integer);
  222.   VAR WaitingTIme: Integer;
  223.   BEGIN
  224.   WaitingTime:= CurrentTime - CurrentPlane.TimeOnQ;
  225.   TotalLandingWait:= TotalLandingWait + WaitingTime;
  226.   If (WaitingTime > MaximumLandingWait) THEN
  227.     MaximumLandingWait:= WaitingTime;
  228.   NumberofLandings:= NumberofLandings + 1;
  229.   Write('Plane #',CurrentPlane.ID:0,' landed at ',CurrentTime:0);
  230.   END;
  231. (*****************************************************************)
  232. (*  Pre-Cond: None.                                              *)
  233. (*  Post-Cond: Process a plane which is taking off.              *)
  234. (*****************************************************************)
  235. PROCEDURE Takeoff(CurrentPlane: PlaneRecType;
  236.                 CurrentTime: Integer;
  237.                 VAR NumberLanded,
  238.                     TotalLandingWait,
  239.                     MaximumLandingWait: Integer);
  240.   VAR WaitingTime: Integer;
  241.   BEGIN
  242.   WaitingTime:= CurrentTime - CurrentPlane.TimeOnQ;
  243.   TotalTakeoffWait:= TotalTakeoffWait + WaitingTime;
  244.   If (WaitingTime > MaximumTakeoffWait) THEN
  245.     MaximumTakeoffWait:= WaitingTime;
  246.   NumberofTakeoffs:= NumberofTakeoffs + 1;
  247.   Write('Plane #',CurrentPlane.ID:0,' took off at ',CurrentTime:0);
  248.   END;
  249. (*****************************************************************)
  250. (* Pre-Cond: None.                                               *)
  251. (* Post-Cond: Updates variables for idle period                  *)
  252. (*****************************************************************)
  253. PROCEDURE IdleL(CurrentTime: Integer; VAR IdleTimeLand: Integer);
  254.   BEGIN
  255.   IdleTimeLand:= IdleTimeLand + 1;
  256.   Writeln('Runway L is idle at ',CurrentTime:0);
  257.   END;
  258. (*****************************************************************)
  259. (* Pre-Cond: None.                                               *)
  260. (* Post-Cond: Updates variables for idle period                  *)
  261. (*****************************************************************)
  262. PROCEDURE IdleT(CurrentTime: Integer; VAR IdleTimeTakeoff: Integer);
  263.   BEGIN
  264.   IdleTimeTakeoff:= IdleTimeTakeoff + 1;
  265.   Writeln('Runway T is Idle at ',CurrentTime:0);
  266.   END;
  267. (*****************************************************************)
  268. (* Pre-Cond: None.                                               *)
  269. (* Post-Cond: Writes out a summary of the activity.              *)
  270. (*****************************************************************)
  271. PROCEDURE Conclude(
  272.             VAR  LandingQ,
  273.                  TakeoffQ:       Queuetype;
  274.             VAR  CurrentPlane:   PlaneRecType;
  275.                  EndTime,
  276.                  NumberOfPlanes,
  277.                  NumberofLandings,
  278.                  NumberOfTakeoffs,
  279.                  NumberRefused,
  280.                  TotalLandingWait,
  281.                  TotalTakeoffWait,
  282.                  MaximumLandingWait,
  283.                  MaximumTakeoffWait,
  284.                  Idletime:           Integer);
  285.  
  286. BEGIN
  287. Writeln;
  288. IF CurrentTime <= EndTime THEN
  289.  Writeln('Simulation has concluded after ',EndTime:0,' units.')
  290. ELSE
  291.  Writeln('Simulation has concluded after ',CurrentTime:0,' units.');
  292. Writeln('Total number of planes: ',NumberofPlanes:0);
  293. Writeln('  Number of planes landed: ',NumberofLandings:0);
  294. Writeln('  Number of planes taking off: ',NumberofTakeoffs:0);
  295. Writeln('Number of planes turned away: ',NumberRefused:0);
  296. Writeln;
  297. Writeln('  LANDING WAIT               TAKEOFF WAIT');
  298. Writeln('Avg.      Max.             Avg.     Max.');
  299. Writeln;
  300. IF (NumberofLandings = 0) OR (NumberofTakeoffs = 0) THEN
  301.   Writeln( 'ZERO DIV')
  302. ELSE
  303.   BEGIN
  304.   Write(TotalLandingWait/NumberofLandings:2:2, MaximumLandingWait:4);
  305.     Writeln(TotalTakeoffWait/NumberofTakeoffs:20:2, MaximumTakeoffWait:4);
  306.   END;
  307. Writeln;
  308. Writeln('Percentage of time idle on T: ',IdletimeTakeoff/EndTime*100:2:2);
  309. Writeln;
  310. Writeln('Percentage of time idle on L: ',IdletimeLand/EndTime*100:2:2);
  311. Writeln;
  312. Write('Percentage of time idle: ');
  313. Writeln(((IdletimeLand+IdletimeTakeoff)/EndTime*100)/2:2:2);
  314. Writeln;
  315. END;
  316. (*****************************************************************)
  317. (*********************  MAIN  ************************************)
  318. (*****************************************************************)
  319. BEGIN
  320. Initialize;       (* Many global variables *)
  321. CreateQ(LandingQ);
  322. CreateQ(TakeoffQ);
  323.  
  324. FOR CurrentTime := 1 to EndTime DO (* Main Loop of Simulation *)
  325.   BEGIN
  326.     FOR Counter:= 1 TO Poisson(ExpectedArrivals) DO (* Process arrivals   *)
  327.     BEGIN                                         (* onto Landing queue *)
  328.     NumberofPlanes:= NumberofPlanes + 1;
  329.     CurrentPlane.ID:= NumberofPlanes;
  330.     CurrentPlane.TimeonQ:= CurrentTime;
  331.     IF FullQ(LandingQ) THEN
  332.       BEGIN
  333.         Refuse(CurrentPlane, NumberRefused);
  334.         BackLog := True;
  335.       END
  336.     ELSE
  337.       Append(LandingQ, CurrentPlane);
  338.     END;
  339.  
  340.   FOR Counter:= 1 TO Poisson(ExpectedDepartures) DO (* Process Departures *)
  341.     BEGIN                                           (* onto Takeoff queue *)
  342.     NumberofPlanes:= NumberofPlanes + 1;
  343.     CurrentPlane.ID:= NumberofPlanes;
  344.     CurrentPlane.TimeonQ:= CurrentTime;
  345.     IF FullQ(TakeoffQ) THEN
  346.       Refuse(Currentplane, NumberRefused)
  347.     ELSE
  348.       Append(TakeoffQ, CurrentPlane);
  349.     END;
  350.   IF BackLog AND EmptyQ(LandingQ) THEN
  351.      BackLog := False;
  352.  
  353.   IF BackLog AND not EmptyQ(LandingQ) THEN
  354.      BEGIN                               (* First priority to *)
  355.      Serve(LandingQ, CurrentPlane);      (* planes waiting to land.  *)
  356.      Land(CurrentPlane, CurrentTime, NumberofLandings, 
  357.            TotalLandingWait, MaximumLandingWait);
  358.      Writeln(' on runway L');               (* Landing on runway L *)
  359.      IF not EmptyQ(LandingQ) THEN
  360.         BEGIN
  361.         Serve(LandingQ, CurrentPlane);
  362.         Land(CurrentPlane, CurrentTime, NumberofLandings,
  363.                TotalLandingWait, MaximumLandingWait);
  364.         Writeln(' on runway T');
  365.         END
  366.      ELSE
  367.         BEGIN
  368.         BackLog := False;
  369.         IdleL(CurrentTime, IdleTimeLand);
  370.         END;
  371.     END
  372. ELSE
  373.   {===============================================================}
  374.      IF not EmptyQ(LandingQ) THEN
  375.          BEGIN
  376.          Serve(LandingQ, CurrentPlane);
  377.          Land(CurrentPlane, CurrentTime, NumberofLandings,
  378.               TotalLandingWait, MaximumLandingWait);
  379.          Writeln(' on runway L');
  380.          IF not EmptyQ(TakeoffQ) THEN
  381.             BEGIN
  382.             Serve(TakeoffQ, CurrentPlane);
  383.             Takeoff(CurrentPlane, CurrentTime, NumberofTakeoffs,
  384.                  TotalTakeoffWait, MaximumTakeoffWait);
  385.             Writeln(' on runway T');
  386.             END
  387.          ELSE
  388.             BEGIN
  389.             IF not EmptyQ(LandingQ) THEN
  390.                BEGIN
  391.                Serve(LandingQ, CurrentPlane);
  392.                Land(CurrentPlane, CurrentTime, NumberofLandings,
  393.                     TotalLandingWait, MaximumLandingWait);
  394.                Writeln(' on runway T')
  395.                END
  396.             ELSE
  397.                 BEGIN
  398.                 IdleT(CurrentTime, IdleTimeTakeoff);
  399.                 END;
  400.             END;
  401.    END
  402.  ELSE
  403.      IF not EmptyQ(TakeoffQ) THEN
  404.         BEGIN
  405.         Serve(TakeoffQ, CurrentPlane);
  406.         Takeoff(CurrentPlane, CurrentTime, NumberofTakeoffs,
  407.               TotalTakeoffWait, MaximumTakeoffWait);
  408.         Writeln(' on runway L');
  409.         IF not EmptyQ(TakeoffQ) THEN
  410.            BEGIN
  411.            Serve(TakeoffQ, CurrentPlane);
  412.            Takeoff(CurrentPlane, CurrentTime, NumberofTakeoffs,
  413.                  TotalTakeoffWait, MaximumTakeoffWait);
  414.            Writeln(' on runway T');
  415.            END
  416.         ELSE
  417.            BEGIN
  418.            IdleL(CurrentTime, IdleTimeLand);
  419.            IdleT(CurrentTime, IdleTimeTakeoff);
  420.            END;
  421.         END
  422.      ELSE
  423.         BEGIN
  424.         IdleL(CurrentTime, IdleTimeLand);
  425.         IdleT(CurrentTime, IdleTimeTakeoff);
  426.         END;
  427.  
  428. END;  (************* FOR LOOP ************)
  429.  
  430.  
  431.  
  432.  
  433. Conclude(               (* Write summary statistics *)
  434.      LandingQ,
  435.      TakeoffQ,
  436.      CurrentPlane,
  437.      EndTime,
  438.      NumberOfPlanes,
  439.      NumberofLandings,
  440.      NumberOfTakeoffs,
  441.      NumberRefused,
  442.      TotalLandingWait,
  443.      TotalTakeoffWait,
  444.      MaximumLandingWait,
  445.      MaximumTakeoffWait,
  446.      Idletime);
  447. END.
  448.